home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / c / library / xplatfrm / tierra / genebank.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-26  |  19.9 KB  |  643 lines

  1. /* genebank.c  19-8-91  genebank manager for the tierra simulator */
  2. /** Tierra Simulator V3.0: Copyright (c) 1991 Thomas S. Ray **/
  3. /* rationale for genebank function are commented at the end of this file */
  4.  
  5. #include "license.h"
  6.  
  7. #ifndef lint
  8. static char     sccsid[] = "@(#)genebank.c    2.5 8/27/91";
  9. #endif
  10.  
  11. #include "tierra.h"
  12. #include "extern.h"
  13. #include <errno.h>
  14.  
  15. void GetGenFileList() /* read list from disk, and set up list in memory */
  16. {   I8s   data[80]; /* when program starts up */
  17.     I32s  size, i, j, k, gi, ng, onum;
  18.     FILE  *inl;
  19.     Psl   tsl;
  20.     Pgl   sgl = (Pgl) thcalloc(1, sizeof(struct g_list));
  21.  
  22.     num_genq = 0;
  23. #ifdef IBM3090
  24.     sprintf(data,"list.io.d");
  25. #else
  26.     sprintf(data,"%slist", GenebankPath);
  27. #endif
  28.     inl = fopen(data,"r");
  29.     if (inl == NULL)
  30.     {   sprintf(mes[0],"GetGenFileList: file %s not opened, exiting", data);
  31.         FEMessage(1);
  32.         while(hangup) ;
  33.         exit(0);
  34.     }
  35.     fgets(data,79,inl);
  36.     sscanf(data,"NumSizes: %ld  num_gentypes: %ld",&NumSiz,&num_gen);
  37.     siz_sl = ((NumSiz / 20L) + 1L) * 20L + 20L;
  38.     NumSizl = NumSiz;
  39.     num_genl = num_gen;
  40.     tsl = (Psl) thcalloc((I32u) siz_sl, (I32u) sizeof(struct s_list));
  41.     if (tsl == NULL)
  42.     {   sprintf(mes[0],"Tierra GetGenFileList tsl thcalloc error");
  43.         FEMessage(1);
  44.         while(hangup) ;
  45.         exit(0);
  46.     }
  47.     else sl = tsl;
  48.     for (i = 0; i < NumSiz; i++) /* read list of sizes and # gens of each */
  49.     {   if (fgets(data,79,inl) == NULL) break;
  50.         data[strlen(data) - 1] = 0;
  51.         tsl = sl + i;
  52.         sscanf(data,"%ld%ld", &tsl->size, &tsl->num);
  53.         tsl->num_s = tsl->num;
  54.         tsl->a_num = tsl->num + 20;
  55.         tsl->g = (Pgl) thcalloc((I32u) tsl->a_num, sizeof(struct g_list));
  56.         if (tsl->g == NULL)
  57.         {   sprintf(mes[0],"Tierra GetGenFileList sl.g thcalloc error");
  58.             FEMessage(1);
  59.             while(hangup) ;
  60.             exit(0);
  61.         }
  62.         for (j=0; j < tsl->a_num; j++) InitGList(tsl->g + j, i, j, tsl->size);
  63.     }
  64.     for (i = 0; i < NumSiz; i++) /* read list of genotypes */
  65.     {   tsl = sl + i;
  66.         ng = tsl->num;
  67.         for (j = 0; j < ng; j++)
  68.         {   if (fgets(data,79,inl) == NULL) break;
  69.             sscanf(data,"%ld%s%f%f%ld", &size, sgl->gen.label,
  70.                 &sgl->MaxPropPop, &sgl->MaxPropInst, &sgl->bits);
  71. #ifdef IBM3090
  72.             Ebcdic2Ascii(sgl->gen.label);
  73. #endif
  74.             gi = Lbl2Int(sgl->gen.label);
  75.             sgl->b.si = sgl->a.si = i;
  76.             sgl->b.gi = sgl->a.gi = gi;
  77.             if (gi >= tsl->a_num)
  78.             {   onum = tsl->a_num;
  79.                 tsl->a_num = gi + 4;
  80.                 tsl->g = (Pgl) threalloc((I8s Hp) tsl->g,
  81.                 (I32u) sizeof(struct g_list) * tsl->a_num);
  82.                 for (k = onum; k < tsl->a_num; k++)
  83.                     InitGList(tsl->g + k, i, k, tsl->size);
  84.             }
  85.             sgl->gen.size = size;
  86.             *(tsl->g + gi) = *sgl;
  87.         }
  88. #ifdef ERROR
  89.         if (size != tsl->size)
  90.         {   sprintf(mes[0],"Tierra GetGenFileList size match error");
  91.             FEMessage(1);
  92.             while(hangup) ;
  93.             exit(0);
  94.         }
  95. #endif
  96.     }
  97.     thfree(sgl);
  98.     fclose(inl);
  99. }
  100.  
  101. void InitGList(g, si, gi, size)
  102.     Pgl   g;
  103.     I32s  si, gi, size;
  104. {
  105.     g->pop = 0;
  106.     g->bits = 0;
  107.     g->gen.label[0] = g->gen.label[1] = g->gen.label[2] = 45;
  108.     g->gen.label[3] = 0; /* "---" */
  109.     g->gen.size = size;
  110.     g->parent.label[0] = g->parent.label[1] = g->parent.label[2] = 45;
  111.     g->parent.label[3] = 0; /* "---" */
  112.     g->parent.size = 0;
  113.     g->d1.inst = g->d1.flags = g->d1.mov_daught = g->d1.BreedTrue = 0;
  114.     g->d2.inst = g->d2.flags = g->d2.mov_daught = g->d2.BreedTrue = 0;
  115.     g->originI.i = g->originI.m = g->originC = 0;
  116.     g->MaxPropPop = g->MaxPropInst = 0;
  117.     g->comments = NULL; g->genome = NULL, g->gbits = NULL;
  118.     g->b.si = g->a.si = si;
  119.     g->b.gi = g->a.gi = gi;
  120. }
  121.  
  122. void find_gl(g,gli) /* find the list index of a certain genotype */
  123.     struct genotype  *g;
  124.     struct gl_index  *gli;
  125. {
  126.     I32s  i, j;
  127.  
  128.     for (i = 0; i < NumSizl; i++) if (g->size == (sl + i)->size) {
  129.     for (j = 0; j < (sl + i)->num; j++)
  130.         if (!strcmp(g->label,((sl + i)->g + j)->gen.label)) {
  131.         gli->si = i; gli->gi = j;
  132.             return ;
  133.         }
  134.     }
  135.     sprintf(mes[0],"Tierra find_gl error");
  136.     if (!hangup)
  137.         FEMessage(1);
  138.     else
  139.     {   sprintf(mes[1],"system being saved to disk");
  140.         FEMessage(2);
  141.     }
  142.     while(hangup) ;
  143.     WriteSoup(1);
  144.     exit(0);
  145. }
  146.  
  147. void CheckGenotype(ci,gli)    /* check if ci is a new genotype */
  148.     I32s  ci;
  149.     struct gl_index  *gli;
  150. {
  151.     IsNewSize(ci,gli);
  152.     if (IsInGenQueue(ci,gli)) return ;
  153.     if (IsInGenBank(ci,gli)) return ;
  154.     NewGenotype(ci,gli);      /* register new genotype in the lists */
  155. }
  156.  
  157. void IsNewSize(ci,gli)
  158.     I32s  ci;
  159.     struct gl_index  *gli;
  160. {
  161.     I32s  i;
  162.     Psl   tsl;
  163.     Pgl   tgl;
  164.  
  165.     for (i = 0; i < NumSizl; i++)
  166.         if ((sl + i)->size == (cells + ci)->mm.s) {
  167.         gli->si = i;
  168.             return ;
  169.         }
  170.     if (++NumSizl > siz_sl)
  171.     {   siz_sl += 20;
  172.         tsl = (Psl) threalloc((I8s Hp) sl, sizeof(struct s_list) * siz_sl);
  173.         if (tsl == NULL)
  174.         {   sprintf(mes[0],"Tierra IsNewSize threalloc error");
  175.             if (!hangup)
  176.                 FEMessage(1);
  177.             else
  178.             {   sprintf(mes[1],"system being saved to disk");
  179.                 FEMessage(2);
  180.             }
  181.             while(hangup) ;
  182.             WriteSoup(1);
  183.             exit(0);
  184.         }
  185.         else sl = tsl;
  186.         sprintf(mes[0],"lgeneban: realloc, siz_sl = %ld", siz_sl);
  187.         FEMessage(1);
  188.         for (i = siz_sl - 20; i < siz_sl; i++)
  189.         {   tsl = sl + i;
  190.             tsl->size = tsl->num = tsl->num_s = tsl->num_q = tsl->a_num = 0;
  191.             tsl->g = NULL;
  192.         }
  193.     }
  194.     (sl + NumSizl - 1)->size = (cells + ci)->mm.s;
  195.     (sl + NumSizl - 1)->a_num = 20;
  196.     tgl = (sl + NumSizl - 1)->g = (Pgl) thcalloc(20, sizeof(struct g_list));
  197.     for (i = 0; i < 20; i++)
  198.         InitGList(tgl + i, NumSizl - 1, i, (cells + ci)->mm.s);
  199.     gli->si = NumSizl - 1;
  200.     return ;
  201. }
  202.  
  203. I8s  IsInGenQueue(ci,gli)
  204.     I32s  ci;
  205.     struct gl_index  *gli;
  206. {   
  207.     Pcells  ce = cells + ci;
  208.     I32s  i;
  209.     Pgl  tgl;
  210.     Psl  tsl;
  211.  
  212.     tsl = sl + gli->si;
  213.     for (i = 0; i < tsl->num; i++)
  214.     {   tgl = tsl->g + i;
  215.         if (tgl->genome != NULL &&
  216.             IsSameGen(ce->mm.s,(HpInst)(soup + ce->mm.p),tgl->genome))
  217.         {   gli->gi = i;
  218.             ce->d.gli = *gli;
  219.             strcpy(ce->d.gen.label,tgl->gen.label);
  220.             MovToTopGenQueue(gli);
  221.             return 1;
  222.         }
  223.     }
  224.     return 0;
  225. }
  226.  
  227. I8s IsInGenBank(ci,gli) /* check to see if ci is in the disk genebank */
  228.     I32s  ci;
  229.     struct gl_index  *gli;
  230. {
  231.     Pcells ce = cells + ci;
  232.     I32s i, j;
  233.     I8s gfile[80];
  234.     Psl tsl = (sl + gli->si);
  235.     Pgl tgl, g = 0;
  236.     FILE *afp;
  237.     head_t head;
  238.     indx_t *indx;
  239.  
  240. #ifdef IBM3090
  241.     sprintf(gfile,"%04ld.gen.d", tsl->size);
  242. #else
  243.     sprintf(gfile,"%s%04ld.gen", GenebankPath, tsl->size);
  244. #endif
  245.  
  246.     if (!(afp = fopen(gfile, "rb")))
  247.     {   if (errno == ENOENT) return 0;
  248.         perror("IsInGenBank");
  249.         exit(9);
  250.     }
  251.     head = read_head(afp);
  252.  
  253. /*
  254. head.magic[3] = '1';
  255. */
  256.  
  257.     if (strncmp(head.magic, "tie", 3) || head.magic[3] - '0' != INST)
  258.     {   fprintf(stderr, "IsInGenBank: bad magic number");
  259.         exit(10);
  260.     }
  261.     indx = read_indx(afp, &head);
  262.  
  263.     for (i=0; i<tsl->num; i++) /* read all gens of this size from disk */
  264.     {   tgl = tsl->g + i; /* tgl = the ith genotype of this size */
  265.         if (tgl->genome == NULL && (IsBit(tgl->bits,0) || tgl->pop > 0))
  266.             /* check only genotypes that are not in RAM bank, but which */
  267.            /* have been saved to disk (either permanent or temporary names) */
  268.  
  269.         {   if ((j = find_gen(indx, tgl->gen.label, head.n)) == head.n)
  270.             {   fprintf(stderr, "%s not in archive\n", tgl->gen.label);
  271.                 continue;
  272.             }
  273.             g = get_gen(afp, &head, &indx[j], j);
  274.  
  275.             if (IsSameGen(ce->mm.s, (HpInst) (soup + ce->mm.p), g->genome))
  276.                 /* if disk genotype matches soup genotype */
  277.                 /* name cell and put genotype in genequeue */
  278.             {   strcpy(ce->d.gen.label,tgl->gen.label);
  279.                 ce->d.gli.si = gli->si; ce->d.gli.gi = gli->gi = i;
  280.                 *tgl = *g;
  281.                 AddTopGenQueue(gli); /* define gli.gi, and place in queue */
  282.                 thfree(g);
  283.                 fclose(afp);
  284.                 return 1;
  285.             }
  286.             else if (!RamBankSiz || num_genq < RamBankSiz)
  287.             {   gli->gi = i;
  288.                 *tgl = *g;
  289.                 AddTopGenQueue(gli);
  290.             }
  291.             else if (g->genome)
  292.             {   thfree(g->genome);
  293.                 g->genome = NULL;
  294.             }
  295.             if (g) thfree(g);
  296.         }
  297.     }
  298.     thfree(indx);
  299.     fclose(afp);
  300.     return 0;
  301. }
  302.  
  303. void NewGenotype(ci,gli) /* add a new genotype to the RAM list */
  304.     I32s  ci;
  305.     struct gl_index  *gli;
  306. {
  307.     Pcells  ce = cells + ci;
  308.     Psl  tsl = (sl + gli->si); /* point to this size in size list */
  309.     Pgl  tgl;
  310.     I32s  i, j;
  311.     I8s  found = 0;
  312.  
  313.     for (i = 0; i < tsl->num; i++)  /* find a free name if there is one */
  314.     {   tgl = tsl->g + i;
  315.         if (!IsBit(tgl->bits,0) && tgl->pop < 1)
  316.         {   gli->gi = i;
  317.             found = 1;
  318.             break;
  319.         }
  320.     }
  321.     if (!found) AddToGl(gli);  /* if no free name, make a new one */
  322.     tgl = tsl->g + gli->gi;       /* point to this new genotype */
  323.     strcpy(ce->d.gen.label,tgl->gen.label);
  324.     tgl->d1.inst = tgl->d1.flags = tgl->d1.mov_daught = tgl->d1.BreedTrue = 0;
  325.     tgl->d2.inst = tgl->d2.flags = tgl->d2.mov_daught = tgl->d2.BreedTrue = 0;
  326.     if (tgl->genome == NULL)
  327.     {   AddTopGenQueue(gli);
  328.         tgl->genome = (HpInst) thcalloc(tsl->size, sizeof(Instruction));
  329.         if (tgl->genome == NULL)
  330.         {   sprintf(mes[0],"Tierra NewGenotype thcalloc error 1");
  331.             if (!hangup)
  332.                 FEMessage(1);
  333.             else
  334.             {   sprintf(mes[1],"system being saved to disk");
  335.                 FEMessage(2);
  336.             }
  337.             while(hangup) ;
  338.             WriteSoup(1);
  339.             exit(0);
  340.         }
  341.     }
  342.     if (tgl->gbits == NULL)
  343.     {   tgl->gbits = (HpGenB) thcalloc(tsl->size, sizeof(GenBits));
  344.         if (tgl->gbits == NULL)
  345.         {   sprintf(mes[0],"Tierra NewGenotype thcalloc error 2");
  346.             if (!hangup)
  347.                 FEMessage(1);
  348.             else
  349.             {   sprintf(mes[1],"system being saved to disk");
  350.                 FEMessage(2);
  351.             }
  352.             while(hangup) ;
  353.             WriteSoup(1);
  354.             exit(0);
  355.         }
  356.     }
  357.     else if (!found) AddTopGenQueue(gli);
  358.     else MovToTopGenQueue(gli);
  359.     for (i = 0; i < tsl->size; i++)
  360.     {   for (j = 0; j < PLOIDY; j++)
  361.         {   tgl->genome[i][j] = soup[ad(ce->mm.p + i)][j];
  362.         }
  363.     }
  364.     tgl->originC = time(NULL);
  365.     tgl->originI = InstExe;
  366.     tgl->parent = ce->d.parent;
  367.     tgl->bits = 0; tgl->pop = 0;
  368.     if (reaped)
  369.     {   tgl->MaxPropPop = (float) 1 / (float) NumCells;
  370.         tgl->MaxPropInst = (float) tsl->size / (float) SoupSize;
  371.     }
  372.     tgl->ploidy = ce->d.ploidy;
  373.     tgl->track = ce->c.tr;
  374. }
  375.  
  376. I32u WhoIs(ci, a)
  377.     I32s  *ci;
  378.     Ind   a;
  379. {
  380.     Pcells  ce = cells + *ci;
  381.     I8s     md;
  382.  
  383.     if (a >= ce->mm.p && a < ce->mm.p + ce->mm.s) return 0; /* same cell */
  384.     if (a >= ce->md.p && a < ce->md.p + ce->md.s) return 1;/* daughter cell */
  385.     if (IsFree(a)) return 3; /* is free memory */
  386.     WhichCell(a, ci, &md);
  387.     if (md == 'm') return 2; /* is other cell */
  388.     return 4;     /* is the daughter of another cell */
  389. }
  390.  
  391. void AddToGl(gli)
  392.     struct gl_index  *gli;
  393. {
  394.     I32s  i;
  395.     Psl   tsl = sl + gli->si;
  396.     Pgl   tgl;
  397.     I8s   aaalabel[4];
  398.  
  399.     aaalabel[0] = aaalabel[1] = aaalabel[2] = 97;
  400.     aaalabel[3] = 0;
  401.     num_genl++;
  402.     if (++tsl->num >= tsl->a_num) {
  403.     tsl->a_num += 20;
  404.         tsl->g = (Pgl) threalloc((I8s Hp) tsl->g,
  405.             sizeof(struct g_list) * tsl->a_num);
  406.         for (i = tsl->a_num - 20; i < tsl->a_num; i++)
  407.             InitGList(tsl->g + i,gli->si,i,tsl->size);
  408.     }
  409.     tgl = tsl->g + tsl->num - 1;
  410.     gli->gi = tsl->num - 1;
  411.     if (tsl->num == 1) strcpy(tgl->gen.label,aaalabel);
  412.     else IncrLbl(tgl->gen.label,(tgl - 1)->gen.label);
  413.     if (reaped) {
  414.     tgl->MaxPropPop  = (float) 1 / (float) NumCells;
  415.         tgl->MaxPropInst = (float) tsl->size / (float) SoupSize;
  416.     }
  417. }
  418.  
  419. I8s  IsSameGen(size, g1, g2) /* compare two genomes */
  420.     I32s   size;
  421.     HpInst  g1, g2;
  422. {
  423.     I32s  i, j;
  424.  
  425.     for (i = 0; i < size; i++)
  426.     {   for (j = 0; j < PLOIDY; j++)
  427.             if ((g1 + i)[j]->inst != (g2 + i)[j]->inst) return 0;
  428.     }
  429.     return 1;
  430. }
  431.  
  432. void AddTopGenQueue(gli)
  433.     struct gl_index  *gli;
  434. {
  435.     Pgl   tgl;
  436.     Psl   tsl;
  437.  
  438.     tsl = sl + gli->si;
  439.     tgl = tsl->g + gli->gi;
  440.     tsl->num_q++;
  441.     if (!num_genq) gq_top = gq_bot = *gli;
  442.     if(++num_genq > RamBankSiz) DelBotGenQueue();/* free place for genotype */
  443.     tgl->b = gq_top;   /* new top points below to old top of queue */
  444.     ((sl+gq_top.si)->g+gq_top.gi)->a= *gli;/*old top points above to new top*/
  445.     tgl->a = *gli;  /* new top points above to self */
  446.     gq_top = *gli;  /* gli is now the top */
  447. }
  448.  
  449. void MovToTopGenQueue(gli)
  450.     struct gl_index  *gli;
  451. {
  452.     Pgl  tgl;
  453.  
  454.     tgl = (sl + gli->si)->g + gli->gi;
  455.     if (gli->si == gq_top.si && gli->gi == gq_top.gi) return ;
  456.     if (gli->si == gq_bot.si && gli->gi == gq_bot.gi) {
  457.     gq_bot = tgl->a;      /* new bot is above old bot */
  458.         ((sl + gq_bot.si)->g + gq_bot.gi)->b = gq_bot;  /* new bot points */
  459.     }                                                   /* down to self */
  460.     else {   /* next gq points to previous gq */
  461.         ((sl + tgl->b.si)->g + tgl->b.gi)->a = tgl->a;
  462.         ((sl + tgl->a.si)->g + tgl->a.gi)->b = tgl->b;
  463.     }   /* previous gq points to next gq */
  464.     tgl->a = *gli;               /* points up to self, is at top of queue */
  465.     tgl->b = gq_top;           /* points down to old top */
  466.     ((sl+gq_top.si)->g + gq_top.gi)->a = *gli;/*old top points up to new top*/
  467.     gq_top = *gli;              /* gq_top is now gli */
  468. }
  469.  
  470. void DelBotGenQueue()
  471. {   struct gl_index  new_gq_bot;
  472.     Pgl  ogl, ngl;
  473.     Psl  tsl;
  474.     I8s  path[80];
  475.     FILE  *fp;
  476.     head_t head;
  477.     indx_t *indx;
  478.  
  479.     tsl = sl + gq_bot.si;
  480.     ogl = (sl + gq_bot.si)->g + gq_bot.gi;            /* old bottom gl */
  481.     if (ogl->pop > 0 && !IsBit(ogl->bits,0) && ogl->genome != NULL) {
  482. #ifdef IBM3090
  483.         sprintf(path,"%04ld.tmp.d", tsl->size);
  484. #else
  485.     sprintf(path,"%s%04ld.tmp", GenebankPath, tsl->size);
  486. #endif
  487.     fp = open_ar(path, tsl->size, INST, 0);
  488.         head = read_head(fp);
  489.     indx = read_indx(fp, &head);
  490.     add_gen(fp, &head, &indx, ogl);
  491.     fclose(fp);
  492.     }
  493.     new_gq_bot = ogl->a;
  494.     ngl = (sl + new_gq_bot.si)->g + new_gq_bot.gi;    /* new bottom gl */
  495.     ngl->b = new_gq_bot;            /* new bottom gl points down to self */
  496.     if (ogl->genome) {
  497.     thfree(ogl->genome);
  498.         ogl->genome = NULL;
  499.     }
  500.     num_genq--;
  501.     tsl->num_q--;
  502.     ogl->a = ogl->b = gq_bot;
  503.     gq_bot = new_gq_bot;
  504. }
  505.  
  506. void IncrLbl(lbln, lblo)
  507.     I8s   *lbln, *lblo;  /* 97 = a, 122 = z in ASCII */
  508. {   
  509.     strcpy(lbln,lblo);
  510.     if (lbln[2] < 122) {
  511.     lbln[2]++;
  512.         goto finish;
  513.     }
  514.     if (lbln[1] < 122) {
  515.     lbln[1]++;
  516.         lbln[2] = 97;
  517.         goto finish;
  518.     }
  519.     if (lbln[0] < 122) {
  520.     lbln[0]++;
  521.         lbln[1] = 97;
  522.         lbln[2] = 97;
  523.         goto finish;
  524.     }
  525.     finish:
  526.     return ;
  527. }
  528.  
  529. void MaxLbl(lbl, s) /* if s > lbl then lbl = s */
  530.     I8s   *lbl, *s;  /* 97 = a, 122 = z in ASCII */
  531. {   
  532.     if (strcmp(lbl,s) > 0) goto finish;
  533.     if (strcmp(lbl,s) < 0) strcpy(lbl,s);
  534.     if (lbl[2] < 122) {
  535.     lbl[2]++;
  536.         goto finish;
  537.     }
  538.     if (lbl[1] < 122) {
  539.     lbl[1]++;
  540.         lbl[2] = 97;
  541.         goto finish;
  542.     }
  543.     if (lbl[0] < 122) {
  544.     lbl[0]++;
  545.         lbl[1] = 97;
  546.         lbl[2] = 97;
  547.         goto finish;
  548.     }
  549.     finish:
  550.     return ;
  551. }
  552.  
  553. I32s Lbl2Int(s)
  554.     I8s  *s;
  555. {   if(s[0] == '-') return -1;
  556.     return (s[2]- 'a') + (26 * (s[1] - 'a')) + (676 * (s[0] - 'a'));
  557. }
  558.  
  559. void Int2Lbl(i, s)
  560.     I32s  i;
  561.     I8s   *s;
  562. {   if(i < 0)
  563.     {   strcpy(s,"---");
  564.         return;
  565.     }
  566.     s[0] = 'a' + i / 676;
  567.     i %= 676;
  568.     s[1] = 'a' + i / 26;
  569.     i %= 26;
  570.     s[2] = 'a' + i;
  571.     s[3] = 0;
  572. }
  573.  
  574. void DelGenFile(tgl) /* this fn is going away real soon */
  575.     Pgl  tgl;
  576. {
  577.     I8s  comd[99];
  578.  
  579. #ifdef IBM3090
  580.     strcpy(label, tgl->gen.label);
  581.     Ascii2Ebcdic(label);
  582.     sprintf(comd,"erase %04ld%s gen d", tgl->gen.size, label);
  583. #endif
  584. #ifdef unix
  585.     sprintf(comd,"rm %s%04ld%c%04ld%s", GenebankPath,
  586.     tgl->gen.size, SLASH, tgl->gen.size, tgl->gen.label);
  587. #endif
  588. #if __TURBOC__ || OS2_MC
  589.     sprintf(comd,"del %s%04ld%c%04ld%s", GenebankPath,
  590.     tgl->gen.size, SLASH, tgl->gen.size, tgl->gen.label);
  591. #endif
  592.     system(comd);
  593.     SetBit(&tgl->bits, 1, 0);
  594. }
  595.  
  596. /* rationale for the functioning of the genebank:
  597.  
  598. The term ``rambank'' refers to a collection of genotypes maintained in RAM
  599. The term ``diskbank'' refers to a collection of genotypes maintained on disk
  600. The term ``genebank'' refers to both the rambank and the diskbank
  601.  
  602. Genotype names have two parts: size-label, for example 0080aaa, 0045eat,
  603. 6666god.
  604.  
  605. 1) When a creature is born its genotype will be compared to that of its
  606.    parent.
  607.    A) if they are the same, the daughter will be given the same name as the
  608.       mother.
  609.    B) if they are not the same, the genebank will be searched.
  610.       a) if the daughter genotype is found in the genebank, it will be given
  611.          the same name as the genotype that it matches in the bank.
  612.       b) if the daughter genotype does not match any genotype in the bank,
  613.          a new name will be created for it, and it will be entered into the
  614.          rambank.
  615. 2) For each birth and death a count of the population of both the genotype
  616.    and the size class involved will be incremente or decremented, so that we
  617.    have a count of the current population of each genotype and each size
  618.    class.  This information is maintained in rambank.
  619. 3) If a genotype frequency crosses a critical threshold, the genotype name
  620.    will become permanent and the genotype will be saved to the diskbank.
  621.    There may be several types of thresholds: proportion of population
  622.    (e.g., 2%), proportion of soup, or just numbers of creatures.
  623. 4) When a genotype frequency drops to zero:
  624.    A) If the genotype never crossed the thresholds, the genotype will be
  625.       removed from the genebank, and its unique name will become available for
  626.       reuse.
  627.    B) If the genotype crossed the threshold, gaining a permanent name, it
  628.       should be retained in the genebank.
  629. 5) Periodically, Tierra saves the complete state of the machine (e.g., every
  630.    100 million instructions executed).  At that time, the complete rambank
  631.    is saved to the diskbank.  For this reason, 4 A applies also to genotypes
  632.    which never became permanent, and these must be removed from the diskbank
  633.    as well.  The bitfield in the genotype structure tells us if a genotype is
  634.    saved to the diskbank, and if it is permanent.
  635. 6) If the rambank becomes ``too full'', some relatively unused portion of it
  636.    should be swapped to the diskbank.  In DOS, ``too full'' could be signaled
  637.    by a malloc failure.  In unix, ``too full'' could be signaled by some
  638.    specified limit on how big the rambank should get, if this seems wise.
  639.    That portion of the rambank to be swapped to the diskbank might consist of
  640.    the least recently accessed size class.  For this reason it might be
  641.    worthwhile to maintain a queue of size classes, ordered by last use.
  642. */
  643.